
/**
* @name: CurdServicePlugin.java 
*
* @Copyright: (c) 2017 DLFC. All rights reserved. 
*
* @description: 
*
* @version: 1.0
* @date : 2017年1月14日 
* @author: Alex.Ge 
*
* @Modification  History:<br>
*  Date          Author         Version        Discription
*  2017年1月14日       Alex.Ge        1.0             <修改原因描述>
*/
package com.linlion.mybatis.generator.plugins;

import static org.mybatis.generator.internal.util.StringUtility.stringHasValue;
import static org.mybatis.generator.internal.util.messages.Messages.getString;

import java.util.ArrayList;
import java.util.List;

import org.mybatis.generator.api.GeneratedJavaFile;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.ProgressCallback;
import org.mybatis.generator.api.VerboseProgressCallback;
import org.mybatis.generator.api.dom.java.CompilationUnit;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.TopLevelClass;
import org.mybatis.generator.codegen.AbstractGenerator;
import org.mybatis.generator.codegen.AbstractJavaGenerator;
import org.mybatis.generator.config.PropertyRegistry;

import com.linlion.mybatis.generator.codegen.mybatis3.service.CrudServiceGenerator;
import com.linlion.mybatis.generator.config.JavaServiceGeneratorConfiguration;

/**
 * @name: CurdServicePlugin
 * @description:
 * 
 * @version 1.0
 * @author Alex.Ge
 *
 */
public class CurdServicePlugin extends PluginAdapter {

	private final String USEACTUALCOLUMNNAMESEXCLUDEROOT = "useActualColumnNamesExcludeRoot";

	private List<AbstractJavaGenerator> javaServiceGenerators;
	private JavaServiceGeneratorConfiguration javaServiceGeneratorConfiguration;

	// @Override
	//
	// public boolean modelGetterMethodGenerated(Method method, TopLevelClass
	// topLevelClass,
	// IntrospectedColumn introspectedColumn, IntrospectedTable
	// introspectedTable, ModelClassType modelClassType) {
	// String property = introspectedColumn.getJavaProperty();
	// introspectedColumn.setj
	// FullyQualifiedJavaType fqjt = introspectedColumn
	// .getFullyQualifiedJavaType();
	// method = new Method();
	// method.setVisibility(JavaVisibility.PUBLIC);
	// method.setReturnType(fqjt);
	// method.setName(getGetterMethodName(property, fqjt));
	//
	//
	// StringBuilder sb = new StringBuilder();
	// sb.append("return "); //$NON-NLS-1$
	// sb.append(property);
	// sb.append(';');
	// method.addBodyLine(sb.toString());
	//
	// return true;
	// }

	@Override
	public boolean modelFieldGenerated(Field field, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn,
			IntrospectedTable introspectedTable, ModelClassType modelClassType) {
		if ("true".equals(introspectedTable.getTableConfiguration().getProperty(USEACTUALCOLUMNNAMESEXCLUDEROOT))) {
			introspectedColumn.setJavaProperty(introspectedColumn.getActualColumnName());
			field.setName(introspectedColumn.getActualColumnName());
		}
		return true;
	}

	@Override
	public boolean validate(List<String> warnings) {
		context.getJavaClientGeneratorConfiguration();
		javaServiceGenerators = new ArrayList<AbstractJavaGenerator>();
		javaServiceGeneratorConfiguration = new JavaServiceGeneratorConfiguration();
		if (!stringHasValue(properties.getProperty("targetProject"))) {
			warnings.add(getString("ValidationError.28", //$NON-NLS-1$
					"CurdServicePlugin")); //$NON-NLS-1$
			return false;
		}
		if (!stringHasValue(properties.getProperty("targetPackage"))) {
			warnings.add(getString("ValidationError.12", //$NON-NLS-1$
					"CurdServicePlugin", //$NON-NLS-1$
					"validate")); //$NON-NLS-1$
			return false;
		}

		javaServiceGeneratorConfiguration
				.setJavaClientPackage(context.getJavaClientGeneratorConfiguration().getTargetPackage());
		javaServiceGeneratorConfiguration
				.setJavaModelPackage(context.getJavaModelGeneratorConfiguration().getTargetPackage());
		javaServiceGeneratorConfiguration.setTargetPackage(properties.getProperty("targetPackage"));
		javaServiceGeneratorConfiguration.setRootClass(properties.getProperty(PropertyRegistry.ANY_ROOT_CLASS));
		javaServiceGeneratorConfiguration.setTargetProject(properties.getProperty("targetProject"));
		AbstractJavaGenerator javaGenerator = new CrudServiceGenerator(javaServiceGeneratorConfiguration);
		ProgressCallback progressCallback = new VerboseProgressCallback();
		initializeAbstractGenerator(javaGenerator, warnings, progressCallback);
		javaServiceGenerators.add(javaGenerator);
		return true;
	}

	@Override
	public List<GeneratedJavaFile> contextGenerateAdditionalJavaFiles(IntrospectedTable introspectedTable) {
		List<GeneratedJavaFile> answer = new ArrayList<GeneratedJavaFile>();
		for (AbstractJavaGenerator javaGenerator : javaServiceGenerators) {
			javaGenerator.setIntrospectedTable(introspectedTable);
			List<CompilationUnit> compilationUnits = javaGenerator.getCompilationUnits();
			for (CompilationUnit compilationUnit : compilationUnits) {
				GeneratedJavaFile gjf = new GeneratedJavaFile(compilationUnit,
						javaServiceGeneratorConfiguration.getTargetProject(),
						context.getProperty(PropertyRegistry.CONTEXT_JAVA_FILE_ENCODING), context.getJavaFormatter());
				answer.add(gjf);
			}
		}
		return answer;
	}

	private void initializeAbstractGenerator(AbstractGenerator abstractGenerator, List<String> warnings,
			ProgressCallback progressCallback) {
		if (abstractGenerator == null) {
			return;
		}
		abstractGenerator.setContext(context);
		abstractGenerator.setProgressCallback(progressCallback);
		abstractGenerator.setWarnings(warnings);
	}

	public static String getGetterMethodName(String property, FullyQualifiedJavaType fullyQualifiedJavaType) {
		StringBuilder sb = new StringBuilder();

		sb.append(property);
		if (Character.isLowerCase(sb.charAt(0))) {
			if (sb.length() == 1 || !Character.isUpperCase(sb.charAt(1))) {
				sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
			}
		}

		if (fullyQualifiedJavaType.equals(FullyQualifiedJavaType.getBooleanPrimitiveInstance())) {
			sb.insert(0, "is"); //$NON-NLS-1$
		} else {
			sb.insert(0, "get"); //$NON-NLS-1$
		}

		return sb.toString();
	}

}
